package com.lagou.edu.zdy.util;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

/**
 * rpc解码器
 */
public class RpcDecoder extends ByteToMessageDecoder {

    private Class<?> clazz;
    private Serializer serializer;

    public RpcDecoder(Class<?> clazz, Serializer serializer) {
        this.clazz = clazz;
        this.serializer = serializer;
    }

//    @Override
//    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf input, List<Object> list) throws Exception {
//        System.out.println("解密数据");
//        //如果接收到的字节还不到4个字节,也即是连消息长度字段中的内容都不完整的,直接return。
//        if (input.readableBytes()<4) {
//            return;
//        }
//
//        int beginIndex = input.readerIndex();
//        int length = input.readInt();
//
//        //对于拆包这种场景,由于还未读取到完整的消息,bufferIn.readableBytes() 会小于length,
//        // 并重置bufferIn的readerIndex为0,然后退出,ByteToMessageDecoder会乖乖的等待下个包的到来。
//        if (input.readableBytes()<length) {
//            input.readerIndex(beginIndex);
//            return;
//        }
//        //将readerIndex设置为最大。首先代码能执行到这里,针对拆包这种场景而言,已经是读取到一条有效完整的消息了。
//        //这个时候需要通知ByteToMessageDecoder类,bufferIn中的数据已经读取完毕了,不要再调用decode方法了。
//        // ByteToMessageDecoder类的底层会根据bufferIn.isReadable()方法来判断是否读取完毕。
//        // 只有将readerIndex设置为最大,bufferIn.isReadable()方法才会返回false。
//        input.readerIndex(beginIndex+length);
//
//        //当decode方法执行完后,会释放bufferIn这个缓冲区,如果将执行完释放操作的bufferIn传递给下个处理器的话,
//        // 一旦下个处理器调用bufferIn的读或者写的方法时,会立刻报出IllegalReferenceCountException异常的。
//        //因此slice操作后,必须加上一个retain操作,让bufferIn的引用计数器加1,这样ByteToMessageDecoder会刀下留人,先不释放bufferIn。
//        System.out.println("读取长度"+(beginIndex+length));
//        ByteBuf slice = input.readSlice(beginIndex+length);
//        slice.retain();
//
//
//        byte[] bytes = slice.array();
////        int length = input.readInt();
//        Object o = serializer.deserialize(clazz, bytes);
//
//        System.out.println("RpcDecoder "+ o);
//        list.add(o);
//
//    }

    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf bufferIn, List<Object> list) throws Exception {
        System.out.println("数据解密 ");
        int beginIndex = bufferIn.readerIndex();
        int length = bufferIn.readInt();

        if (bufferIn.readableBytes() < length) {
            bufferIn.readerIndex(beginIndex);
            return;
        }

        bufferIn.readerIndex(beginIndex + 4 + length);

        ByteBuf otherByteBufRef = bufferIn.slice(beginIndex +4, length);


        byte[] bytes = new byte[otherByteBufRef.readableBytes()];
        otherByteBufRef.readBytes(bytes);

        System.out.println(new String(bytes,"UTF-8"));
        Object o = serializer.deserialize(clazz, bytes);

        System.out.println("RpcDecoder "+ o);
        list.add(o);
    }
}
